home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / fasttext.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  26KB  |  1,363 lines

  1. /*
  2. Copyright 1992,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. #include "mint.h"
  8. #include "fasttext.h"
  9.  
  10. #ifdef FASTTEXT
  11.  
  12. #ifdef __GNUC__
  13. #define INLINE inline
  14. #define ITYPE long    /* gcc's optimizer likes 32 bit integers */
  15. #else
  16. #define INLINE
  17. #define ITYPE int
  18. #endif
  19.  
  20. #define CONDEV    (2)
  21.  
  22. static SCREEN *current;
  23.  
  24. static void paint P_((SCREEN *, int, char *)),
  25.      paint8c P_((SCREEN *, int, char *)),
  26.      paint816m P_((SCREEN *, int, char *));
  27.  
  28. INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *));
  29. INLINE static void flash P_((SCREEN *));
  30. static void normal_putch P_((SCREEN *, int));
  31. static void escy_putch P_((SCREEN *, int));
  32. static void quote_putch P_((SCREEN *, int));
  33.  
  34. static    char *chartab[256];
  35.  
  36. #define MAX_PLANES 8
  37. static int fgmask[MAX_PLANES], bgmask[MAX_PLANES];
  38.  
  39. static long scrnsize;
  40.  
  41. short hardscroll;
  42. static char *hardbase, *oldbase;
  43.  
  44. typedef void (*Vfunc) P_((SCREEN *, int));
  45.  
  46. #define base *((char **)0x44eL)
  47. #define escy1 *((short *)0x4acL)
  48.  
  49. static Vfunc state;
  50.  
  51. static short hardline;
  52. static void (*vpaint) P_((SCREEN *, int, char *));
  53. static char *rowoff;
  54.  
  55. void init P_((void));
  56. void hardware_scroll P_((SCREEN *));
  57. INLINE static char *PLACE P_((SCREEN *, int, int));
  58. INLINE static void gotoxy P_((SCREEN *, int, int));
  59. INLINE static void clrline P_((SCREEN *, int));
  60. INLINE static void clear P_((SCREEN *));
  61. INLINE static void clrchar P_((SCREEN *, int, int));
  62. INLINE static void clrfrom P_((SCREEN *, int, int, int, int));
  63. INLINE static void delete_line P_((SCREEN *, int));
  64. INLINE static void insert_line P_((SCREEN *, int));
  65. static void setbgcol P_((SCREEN *, int));
  66. static void setfgcol P_((SCREEN *, int));
  67. static void putesc P_((SCREEN *, int));
  68. static void escy1_putch P_((SCREEN *, int));
  69. INLINE static void put_ch P_((SCREEN *, int));
  70.  
  71. /* routines for flashing the cursor for screen v */
  72. /* flash(v): invert the character currently under the cursor */
  73.  
  74. INLINE static void
  75. flash(v)
  76.     SCREEN *v;
  77. {
  78.     char *place;
  79.     ITYPE i, j, vplanes;
  80.  
  81.     vplanes = v->planes + v->planes;
  82.     place = v->cursaddr;
  83.  
  84.     for (j = v->cheight; j > 0; --j) {
  85.         for (i = 0; i < vplanes; i+=2)
  86.             place[i] = ~place[i];
  87.  
  88.         place += v->planesiz;
  89.     }
  90.     v->curstimer = v->period;
  91. }
  92.  
  93. /* make sure the cursor is off */
  94.  
  95. INLINE
  96. static void
  97. curs_off(v)
  98.     SCREEN *v;
  99. {
  100.     if (v->flags & CURS_ON) {
  101.         if (v->flags & CURS_FSTATE) {
  102.             flash(v);
  103.             v->flags &= ~CURS_FSTATE;
  104.         }
  105.     }
  106. }
  107.  
  108. /* OK, show the cursor again (if appropriate) */
  109.  
  110. INLINE static void
  111. curs_on(v)
  112.     SCREEN *v;
  113. {
  114.     if (v->hidecnt) return;
  115.  
  116.     if (v->flags & CURS_ON) {
  117. #if 0
  118.     /* if the cursor is flashing, we cheat a little and leave it off
  119.      * to be turned on again (if necessary) by the VBL routine
  120.      */
  121.         if (v->flags & CURS_FLASH) {
  122.             v->curstimer = 2;
  123.             return;
  124.         }
  125. #endif
  126.         if (!(v->flags & CURS_FSTATE)) {
  127.             v->flags |= CURS_FSTATE;
  128.             flash(v);
  129.         }
  130.     }
  131. }
  132.  
  133. void
  134. init()
  135. {
  136.     SCREEN *v;
  137.     int i, j;
  138.     char *data, *foo;
  139.     static char chardata[256*16];
  140.     register int linelen;
  141.  
  142.     foo = lineA0();
  143.     v = (SCREEN *)(foo - 346);
  144.     
  145.     /* Ehem... The screen might be bigger than 32767 bytes.
  146.        Let's do some casting... 
  147.        Erling
  148.     */
  149.     linelen = v->linelen;
  150.     scrnsize = (v->maxy+1)*(long)linelen;
  151.     rowoff = (char *)kmalloc((long)((v->maxy+1) * sizeof(long)));
  152.     if (rowoff == 0) {
  153.         FATAL("Insufficient memory for screen offset table!");
  154.     } else {
  155.         long off, *lptr = (long *)rowoff;
  156.         for (i=0, off=0; i<=v->maxy; i++) {
  157.             *lptr++ = off;
  158.             off += linelen;
  159.         }
  160.     }
  161.     if (hardscroll == -1) {
  162.     /* request for auto-setting */
  163.         hardscroll = v->maxy+1;
  164.     }
  165.     if (hardscroll > 0) {
  166.         if (!hardbase)
  167.             hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L)
  168.                        & 0xffffff00L);
  169.  
  170.         if (hardbase == 0) {
  171.             ALERT("Insufficient memory for hardware scrolling!");
  172.         } else {
  173.             quickmove(hardbase, base, scrnsize);
  174.             v->cursaddr = v->cursaddr + (hardbase - base);
  175.             oldbase = base;
  176.             base = hardbase;
  177.             Setscreen(hardbase, hardbase, -1);
  178.         }
  179.     }
  180.     hardline = 0;
  181.     if (v->cheight == 8 && v->planes == 2) {
  182.         foo = &chardata[0];
  183.         vpaint = paint8c;
  184.         for (i = 0; i < 256; i++) {
  185.             chartab[i] = foo;
  186.             data = v->fontdata + i;
  187.             for (j = 0; j < 8; j++) {
  188.                 *foo++ = *data;
  189.                 data += v->form_width;
  190.             }
  191.         }
  192.     } else if ((v->cheight == 16 || v->cheight == 8) && v->planes == 1) {
  193.         foo = &chardata[0];
  194.         vpaint = paint816m;
  195.         for (i = 0; i < 256; i++) {
  196.             chartab[i] = foo;
  197.             data = v->fontdata + i;
  198.             for (j = 0; j < v->cheight; j++) {
  199.                 *foo++ = *data;
  200.                 data += v->form_width;
  201.             }
  202.         }
  203.     }
  204.     else
  205.         vpaint = paint;
  206.  
  207.     if (v->hidecnt == 0) {
  208.     /*
  209.      * make sure the cursor is set up correctly and turned on
  210.      */
  211.         (void)Cursconf(0,0);    /* turn cursor off */
  212.  
  213.         v->flags &= ~CURS_FSTATE;
  214.  
  215.     /* now turn the cursor on the way we like it */
  216.         v->hidecnt = 0;
  217.         curs_on(v);
  218.     } else {
  219.         (void)Cursconf(0,0);
  220.         v->flags &= ~CURS_ON;
  221.         v->hidecnt = 1;
  222.     }
  223.  
  224.     current = v;
  225.     /* setup bgmask and fgmask */
  226.     setbgcol(v, v->bgcol);
  227.     setfgcol(v, v->fgcol);
  228.     state = normal_putch;
  229. }
  230.  
  231. /*
  232.  * PLACE(v, x, y): the address corresponding to the upper left hand corner of
  233.  * the character at position (x,y) on screen v
  234.  */
  235. INLINE static
  236. char *PLACE(v, x, y)
  237.     SCREEN *v;
  238.     int x, y;
  239. {
  240.     char *place;
  241.     int i, j;
  242.  
  243.     place = base + x;
  244.     if (y == v->maxy)
  245.         place += scrnsize - v->linelen;
  246.     else if (y) {
  247.         y+=y;    /* Make Y into index for longword array. */
  248.         y+=y;    /* Two word-size adds are faster than a 2-bit shift. */
  249.         place += *(long *)(rowoff + y);
  250.     }
  251.     if ((j = v->planes-1)) {
  252.         i = (x & 0xfffe);
  253.         do place += i;
  254.         while (--j);
  255.     }
  256.     return place;
  257. }
  258.  
  259. /*
  260.  * paint(v, c, place): put character 'c' at position 'place' on screen
  261.  * v. It is assumed that x, y are proper coordinates!
  262.  * Specialized versions (paint8c and paint816m) of this routine follow;
  263.  * they assume 8 line high characters, medium res. and 8 or 16 line/mono,
  264.  * respectively.
  265.  */
  266.  
  267. static void
  268. paint(v, c, place)
  269.     SCREEN *v;
  270.     int c;
  271.     char *place;
  272. {
  273.     char *data, d, doinverse;
  274.     ITYPE j, planecount;
  275.     int vplanes;
  276.     long vform_width, vplanesiz;
  277.  
  278.     vplanes = v->planes;
  279.  
  280.     data = v->fontdata + c;
  281.     doinverse = (v->flags & FINVERSE) ? 0xff : 0;
  282.     vform_width = v->form_width;
  283.     vplanesiz = v->planesiz;
  284.  
  285.     for (j = v->cheight; j > 0; --j) {
  286.         d = *data ^ doinverse;
  287.         for (planecount = 0; planecount < vplanes; planecount++)
  288.           place[planecount << 1]
  289.             = ((d & (char) fgmask[planecount])
  290.                | (~d & (char) bgmask[planecount]));
  291.         place += vplanesiz;
  292.         data += vform_width;
  293.     }
  294. }
  295.  
  296. static void
  297. paint8c(v, c, place)
  298.     SCREEN *v;
  299.     int c;
  300.     char *place;
  301. {
  302.     char *data;
  303.     char d, doinverse;
  304.     char bg0, bg1, fg0, fg1;
  305.     long vplanesiz;
  306.  
  307.     data = chartab[c];
  308.  
  309.     doinverse = (v->flags & FINVERSE) ? 0xff : 0;
  310.     vplanesiz = v->planesiz;
  311.     bg0 = bgmask[0];
  312.     bg1 = bgmask[1];
  313.     fg0 = fgmask[0];
  314.     fg1 = fgmask[1];
  315.  
  316.     if (!doinverse && !bg0 && !bg1 && fg0 && fg1) {
  317.         /* line 1 */
  318.         d = *data++;
  319.         *place = d;
  320.         place[2] = d;
  321.         place += vplanesiz;
  322.  
  323.         /* line 2 */
  324.         d = *data++;
  325.         *place = d;
  326.         place[2] = d;
  327.         place += vplanesiz;
  328.  
  329.         /* line 3 */
  330.         d = *data++;
  331.         *place = d;
  332.         place[2] = d;
  333.         place += vplanesiz;
  334.  
  335.         /* line 4 */
  336.         d = *data++;
  337.         *place = d;
  338.         place[2] = d;
  339.         place += vplanesiz;
  340.  
  341.         /* line 5 */
  342.         d = *data++;
  343.         *place = d;
  344.         place[2] = d;
  345.         place += vplanesiz;
  346.  
  347.         /* line 6 */
  348.         d = *data++;
  349.         *place = d;
  350.         place[2] = d;
  351.         place += vplanesiz;
  352.  
  353.         /* line 7 */
  354.         d = *data++;
  355.         *place = d;
  356.         place[2] = d;
  357.         place += vplanesiz;
  358.  
  359.         /* line 8 */
  360.         d = *data;
  361.         *place = d;
  362.         place[2] = d;
  363.     } else {
  364.         /* line 1 */
  365.         d = *data++ ^ doinverse;
  366.         *place = ((d & fg0) | (~d & bg0));
  367.         place[2] = ((d & fg1) | (~d & bg1));
  368.         place += vplanesiz;
  369.  
  370.         /* line 2 */
  371.         d = *data++ ^ doinverse;
  372.         *place = ((d & fg0) | (~d & bg0));
  373.         place[2] = ((d & fg1) | (~d & bg1));
  374.         place += vplanesiz;
  375.  
  376.         /* line 3 */
  377.         d = *data++ ^ doinverse;
  378.         *place = ((d & fg0) | (~d & bg0));
  379.         place[2] = ((d & fg1) | (~d & bg1));
  380.         place